package main

import (
	"GoGinAutoGenerateCMSE/base"
	"GoGinAutoGenerateCMSE/templates"
	"fmt"
	"github.com/droundy/goopt"
	"github.com/iancoleman/strcase"
	"os"
	"path/filepath"
)

var (
	sqlTable       = goopt.String([]string{"-t", "--table"}, "Test_table", "table name ")
	sqlDatabase    = goopt.String([]string{"-d", "--database"}, "TestDatabase", "database name ")
	routerName     = goopt.String([]string{"-r", "--router"}, "Test_Router", "router name ")
	controllerName = goopt.String([]string{"-c", "--controller"}, "Test_Controller", "controller name ")
	outPutDir      = goopt.String([]string{"-f", "--file-path"}, "Test_OutPut_Dir", "file dir name ")
	//定义的时候用接口定义，而不是用结构体定义。这样才能达到多种实现方式
	controllerBase, modelBase, serviceBase, routerBase base.IBase
	err                                                error
	CurrentPath, _                                     = os.Getwd()
	//import 时取项目路径
	AppPath = filepath.Base(CurrentPath)
)

func init() {
	goopt.Description = func() string {
		return "auto generate service model router "
	}
	goopt.Version = "1.0"
	goopt.Summary = `gen --table tableName --database DBName --router routerName --controller controllerName --file Path ./`

	goopt.Parse(nil)
}

//GoGinAutoGenerateCMSE.exe  --table product_sku_attributes --database laravel-shop --controller controllerName --file-path ./
func main() {
	generateController()
	generateRouter()
	generateModel()
	generateService()
}

func generateController() {
	controllerBase = &base.Base{
		Name: strcase.ToCamel(*sqlTable),
		Format: map[string]string{
			//controller 名字首字母大写
			"{{StructName}}": strcase.ToCamel(*sqlTable),
			// 需要的函数数据返回值为小写
			"{{StructReturnName}}": strcase.ToLowerCamel(*sqlTable),
			//路由组，生成路由文件和写在注释用,和表名一样，一般以_连接
			"{{StructRoute}}": *routerName,
			//包名
			"{{StructAppPath}}": AppPath,
		},
		OutPutDir: *outPutDir,
	}
	_ = generateAction(controllerBase, templates.ControllerTpl, "Controller")

}
func generateService() {
	serviceBase = &base.Base{
		Name: strcase.ToCamel(*sqlTable),
		Format: map[string]string{
			//Service 名字首字母大写
			"{{StructName}}": strcase.ToCamel(*sqlTable),
			// 需要的entity实体
			"{{StructLowerEntityName}}": strcase.ToLowerCamel(*sqlTable),
			//数据库连接 首字母大写
			"{{StructDB}}": strcase.ToCamel(*sqlDatabase),
			//包名
			"{{StructAppPath}}": AppPath,
		},
		OutPutDir: *outPutDir,
	}
	_ = generateAction(serviceBase, templates.ServiceTpl, "Service")

}
func generateRouter() {
	routerBase = &base.Base{
		Name: strcase.ToCamel(*sqlTable),
		Format: map[string]string{
			//controller 名字首字母大写
			"{{StructName}}": strcase.ToCamel(*sqlTable),
			// 需要的函数数据返回值为小写
			"{{StructReturnName}}": strcase.ToLowerCamel(*sqlTable),
			//路由组，生成路由文件和写在注释用,和表名一样，一般以_连接
			"{{StructRoute}}": *routerName,
			//包名
			"{{StructAppPath}}": AppPath,
		},
		OutPutDir: *outPutDir,
	}
	_ = generateAction(routerBase, templates.RouterTpl, "Router")
}

func generateModel() {
	modelBase = &base.Base{
		Name: strcase.ToCamel(*sqlTable),
		Format: map[string]string{
			//model 名字首字母大写
			"{{StructName}}": strcase.ToCamel(*sqlTable),
			// 需要的实体类
			"{{StructLowerEntityName}}": strcase.ToLowerCamel(*sqlTable),
			//包名
			"{{StructAppPath}}": AppPath,
			//数据库连接 首字母大写
			"{{StructDB}}": strcase.ToCamel(*sqlDatabase),
		},
		OutPutDir: *outPutDir,
	}
	_ = generateAction(modelBase, templates.ModelTpl, "Model")
}

func generateAction(base base.IBase, tpl string, fType string) error {
	//GenerateFile这个方法，不需要关心是谁(哪个接口，这里是IBase)创建的，而只需要关注是谁实现[这里是Base]的。这里只是*Base结构体实现了Ibase的方法。
	//fileName := "templates." + tpl + "Tpl"//todo 这里就取不到模版中的var了
	if err = base.GenerateFile(tpl, fType); err != nil {
		fmt.Println("generate "+fType+"失败: ", err)
	}
	fmt.Println("generate " + fType + "成功")
	return nil
}
